package cn.tj.wenda.cloud.bas.service.impl;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import cn.tj.wenda.cloud.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.tj.wenda.cloud.bas.entity.BasLoginInfo;
import cn.tj.wenda.cloud.bas.entity.BasPassword;
import cn.tj.wenda.cloud.bas.entity.BasTenant;
import cn.tj.wenda.cloud.bas.entity.BasUser;
import cn.tj.wenda.cloud.bas.entity.BasUserDept;
import cn.tj.wenda.cloud.bas.entity.BasUserMulti;
import cn.tj.wenda.cloud.bas.entity.LoginHis;
import cn.tj.wenda.cloud.bas.mapper.BasTenantMapper;
import cn.tj.wenda.cloud.bas.mapper.BasUserMapper;
import cn.tj.wenda.cloud.bas.service.BasUserService;
import cn.tj.wenda.cloud.entity.LoginUserInfo;
import cn.tj.wenda.cloud.security.JsonWebToken;
import cn.tj.wenda.cloud.security.SHA256;
import cn.tj.wenda.cloud.util.ConstUtil;
import tk.mybatis.mapper.entity.Example;

@Transactional
@Component
public class BasUserServiceImpl implements BasUserService {
	
	private static final int defaultMaxLen = 50;//限制账号和密码最大长度
	//private static final int defaultMinLen = 5;//限制账号和密码最小长度
	
	@Autowired
	BasTenantMapper basTenantMapper;
	
	@Autowired
	BasUserMapper basUserMapper;

	@Override
	public List<BasUser> select(int start, int limit, String params) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<BasUserMulti> selectUserDept(int start, int limit, String params) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<BasUserMulti> selectUserAndDept(int start, int limit, String params) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int update(String userid, BasUser basUser) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int insert(BasUser basUser) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int delete(String userid) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public BasUser selectByPrimaryKey(String userid) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<BasUserDept> selectUserDeptRef() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int resetPwd(List<String> userIds) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int updatePwd(BasPassword basPassword) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String login(BasLoginInfo basLoginInfo) throws BusinessException {
		String tenantid = StringUtils.trimToEmpty(basLoginInfo.getTenantid());
		String account = StringUtils.trimToEmpty(basLoginInfo.getAccount());
		String pwd = StringUtils.trimToEmpty(basLoginInfo.getPassword());
		
		//校验登录次数使用
		String loginKey = tenantid + "_" + account;
		
		if(StringUtils.isEmpty(account)) {
			throw new BusinessException("000001","账号");
		}
		
		if(StringUtils.isEmpty(pwd)) {
			throw new BusinessException("000001","密码");
		}
		
		if(account.length() > defaultMaxLen) {
			throw new BusinessException("000059","账号",String.valueOf(defaultMaxLen));
		}

		if(pwd.length() > defaultMaxLen) {
			throw new BusinessException("000059","密码",String.valueOf(defaultMaxLen));
		}

		BasTenant basTenant = null;//basTenantMapper.selectByPrimaryKey(tenantid);
		if(basTenant == null) {
			throw new BusinessException("000065");
		}
		
		//0=正常,1=已删除,2=锁定
		//只有状态为正常时才能登录，其他状态不能登录
		if("1".equals(basTenant.getStatus())){//状态为删除，不能登录
			throw new BusinessException("000065");
		}
		else if("2".equals(basTenant.getStatus())){//状态为锁定，不能登录
			throw new BusinessException("000158","已锁定");
		}

		Example example = new Example(BasUser.class);
		example.or().andEqualTo("tenantid",tenantid).andEqualTo("account",account);
		List<BasUser> lstBasUser = basUserMapper.selectByExample(example);
		
		this.checkLoginNum(loginKey);
		
		BasUser loginUser = lstBasUser.get(0);
		
		//0=正常,1=已删除,2=锁定
		//只有状态为正常时才能登录，其他状态不能登录
		if("1".equals(loginUser.getStatus())){//状态为删除，不能登录
			throw new BusinessException("000063");
		}
		else if("2".equals(loginUser.getStatus())){//状态为锁定，不能登录
			throw new BusinessException("000068","锁定");
		}

		//校验密码
		String pwdSha="";
		try {
			pwdSha = SHA256.getSignature(pwd, ConstUtil.SECRETKEY);
		} 
		catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException
				| UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		
		if(pwdSha.equals(loginUser.getPwd()) == false) {
			throw new BusinessException("000062","密码");
		}

		LoginUserInfo loginUserInfo = new LoginUserInfo();
		loginUserInfo.setUserId(loginUser.getUserid());
		loginUserInfo.setAccount(loginUser.getAccount());
		loginUserInfo.setUserName(loginUser.getUsername());
		loginUserInfo.setTenantId(tenantid);
		loginUserInfo.setTenantName(basTenant.getShortname());
		
		String temp = "10";//PropertyReader.configuration().getProperty("token.timelength");
		temp = StringUtils.isEmpty(temp) ? "10" : temp;
		String jwt = JsonWebToken.createJwt(loginUserInfo,Integer.parseInt(temp));

		
		//移除Session中的登录次数
		this.removeSession(loginKey);
		
		//LogInfo.getInstance().addLog(LogMods.bas, Pages.BAS011, LogType.insert, "用户登录，用户ID：" + loginUser.getUserid() + ",token:" + jwt, loginUserInfo);
		
		return jwt;
	}

	@Override
	public List<BasUserDept> selectUserDept(String userId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int saveUserDept(String userId, List<BasUserDept> deptIds) {
		// TODO Auto-generated method stub
		return 0;
	}
	
	private void checkLoginNum(String key) throws BusinessException,RuntimeException  {
		String temp = "6";//PropertyReader.configuration().getProperty("login.num");
		
		ServletContext servletContext = this.getServletContext();
		
		if(servletContext.getAttribute(key) == null) {
			servletContext.setAttribute(key, new LoginHis());
		}

		LoginHis loginHis = (LoginHis)servletContext.getAttribute(key);

		long maxLoginNum = Long.parseLong(temp);
		
		//超时检测
		int last = loginHis.checkLocked();
		if(last > 0) {//已锁定
			throw new BusinessException("000077",String.valueOf(last)+"分钟");
		}
		
		//超出重试次数
		if(loginHis.getLoginNum() >= maxLoginNum) {
			temp ="";// PropertyReader.configuration().getProperty("login.aftertime");
			temp = StringUtils.isEmpty(temp) ? "10" : temp;
			int aftertime = Integer.parseInt(temp) * 60;//系统设置的多长时间后可以解锁
			
			//超出次数锁定
			loginHis.setLocked(true);
			loginHis.setTimeLenth(aftertime);
			servletContext.setAttribute(key, loginHis);
			
			throw new BusinessException("000064",String.valueOf(maxLoginNum),temp);
		}
		
		loginHis.setLoginNum(loginHis.getLoginNum() + 1);
		servletContext.setAttribute(key, loginHis);
	}
	
	private void removeSession(String key) throws RuntimeException {
		ServletContext servletContext = this.getServletContext();
		
		if(servletContext.getAttribute(key) != null) {
			servletContext.removeAttribute(key);
		}
	}
	
	private ServletContext getServletContext() throws RuntimeException{
		HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
		
		if(request == null) {
			throw new RuntimeException("登录次数校验时，获取Request出错，登录次数校验未运行。");
		}
		
		if(request.getSession() == null || request.getSession().getServletContext() == null) {
			throw new RuntimeException("登录次数校验时，获取Session出错，登录次数校验未运行。");
		}
		
		return request.getSession().getServletContext();
	}
}
